package br.unifor.cct.mia.ga;

import java.awt.Color;
import java.util.HashMap;
import java.util.Map;

import weka.gui.explorer.ClustererPanel;
import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.evolutionary.Genotype;
import br.unifor.cct.mia.gui.Graphic;

public class GaIO extends Ga {
	
	private static String[] configuracoes = {
		"br.unifor.cct.mia.xover.XOverPBX",
		"br.unifor.cct.mia.select.TournamentMinimize",
		"br.unifor.cct.mia.evaluate.WekaIOCobwebEvaluate",
		"br.unifor.cct.mia.mutation.MutationExclusive",
		"br.unifor.cct.mia.initialize.ExclusiveInitialize"
	};
	
	private Structure structure;
	private Database dbOriginal;
	private Graphic graphic;	
	private Map genesAnt;
	private String dataset;
	private ClustererPanel panel;
	private String dataEstruct;
	private int count = 0;
	
	public GaIO(Database dbOriginal, Structure structure, String dataset, String dataEstruct, ClustererPanel panel, String[] options) {
		super(dbOriginal.size(), configuracoes, options);
		this.dbOriginal = dbOriginal;
    	this.structure = structure;
    	this.dataset = dataset;
    	this.panel = panel;
    	this.dataEstruct = dataEstruct;
    	this.genesAnt = new HashMap();
		createGraphic();
	}
	
	protected void elitist() {
		//graphic.addPointLinha(1, generation, population[indexBestWorst[0]].getFitness());
		graphic.addPointLinha(2, generation, population[indexBestWorst[1]].getFitness());    	
		graphic.addPointLinha(3, generation, sum/configurations.getPopsize());    	
		
		if (population[indexBestWorst[0]].getFitness() == population[configurations.getPopsize()].getFitness()) {
    		count++;
    		if (count == 10) {
    			configurations.setPmutation(0.6);
    		}
    	}
    	else {
    		count = 0;
    		configurations.setPmutation(0.15);
    	}
    	
        if (population[indexBestWorst[0]].getFitness() < population[configurations.getPopsize()].getFitness())
            population[configurations.getPopsize()] = (Genotype)((Genotype)population[indexBestWorst[0]]).clone();
        else
            population[indexBestWorst[1]] = (Genotype)((Genotype)population[configurations.getPopsize()]).clone();
		
		graphic.addPointLinha(0, generation, population[configurations.getPopsize()].getFitness());    	
	}
	
	public Object[] getObjectsMutate() {
		Object[] o = new Object[1];
		o[0] = this;		
		return o;
	}
	
	public Object[] getObjectsSelect() {
		Object[] o = new Object[1];
		o[0] = this;
		return o;
	}
	
	public Object[] getObjectsEvaluate() {
		Object[] o = new Object[5];
		o[0] = dataEstruct;
		o[1] = genesAnt;
		o[2] = dataset;
		o[3] = panel;	
		o[4] = this;
		return o;
	}
	
	public Object[] getObjectsCrossover() {
		Object[] o = new Object[1];
		o[0] = this;
		return o;
	}
	
	public Object[] getObjectsInitialize() {
		Object[] o = new Object[2];
		o[0] = new Integer(dbOriginal.size());
		o[1] = this;
		return o;
	}
	
	private void createGraphic() {
		graphic = new Graphic("Fitness Evaluation", "Generation", "Cost");
		
		graphic.createLine(0, "Best General Fitness");
		graphic.setColorLinha(0, Color.blue);
		
		graphic.createLine(1, "Best Population Fitness");
		graphic.setColorLinha(1, Color.green);
		
		graphic.createLine(2, "Worst Population Fitness");
		graphic.setColorLinha(2, Color.black);
		
		graphic.createLine(3, "Average Population Fitness");
		graphic.setColorLinha(3, Color.red);    	
	}    
}
